
--~ __version__ = 0.27  #f05624a07:36


--****
-- === trigmath
-- formula conversion
-- <<LEVELTOC depth=2>>

namespace trig


include std/math.e


--**
-- 
--get attempt to redefine abs, then rename then get abs undefined @x[i]=
public function seqabs(object x)
  if atom(x) then
    if x < 0 then return -x else return x end if
  else
    for i = 1 to length(x) do
      x[i] = seqabs(x[i])
    end for
  end if
 return x
end function


--**
-- 
public function seqmin(sequence s)
 atom m
  m = 1
  for i = 1 to length(s) do
    if s[m] > s[i] then m = i end if
  end for
  return m
end function


--**
-- 
public function seqmax(sequence s)
 atom m
  m = 1
  for i = 1 to length(s) do
    if s[m] < s[i] then m = i end if
  end for
  return m
end function




--**
-- 
public function frac(atom x)
    if abs((floor(x))) = x then 
         return 0
    end if
         
  return x - floor(x)
end function



--**
-- 
public function fact(atom x)
   if x = 1 then
      return 1
   end if
 
  return ( x * fact(x -1))  
end function

       
--attermpt to make fib reentrent, going to need to be a sequence
--and it could grow out of bounds if only need a few could be countrer productive
public atom prev
prev = 2


--**
-- 
-- note: for n>16? use the routins in permcomb
public function fib(atom n)
atom previous,current,new

    if n = 0 then
        return 0
    elsif n = 1 then
        return 1
    elsif n = prev then
        return prev
   else 
        previous = 0
        current =1
        for i = prev to n do
            new = previous + current
            previous = current
            current = new
        end for
        --prev = new
        return new
    end if
end function




--**
-- 
public function dec_frac(atom x1)
atom numerator, denominator
numerator = 1
denominator = 2
    for q = denominator to 1000 do
        for r = numerator to q - 1 do
          if abs(x1 - (r/q)) < .00003  then
            return {r,q}
          end if
        end for 
    end for    
end function



       



--**
-- note: for n>10 use the routins in permcomb
public function perm_n_by_r(atom n, atom r)
  return fact(n)/fact(n-r)
end function
          


--**
-- 
public procedure pascal_triangle(atom rows)
       atom c
         for n = 0  to rows-1  do
           for r = 0  to n   do
             c = 1
             for x = n  to n-r+1  by -1  do
               c=c*x/(n-x+1)
             end for
             printf(1,"%d ",c)
            end for
            puts(1,"\n")
          end for
        end procedure
          

sequence c


--**
-- 
public function matrix_add(sequence a,sequence b,atom row,atom column,atom s)
     c= repeat (repeat({0},row),column)
     for j = 1  to row   do
        for i = 1 to column do
            if s = 2 then
                b[j][i] = -b[j][i] 
            end if
            c[j][i] = { a[j][i] + b[j][i]}
        end for
    end for
    return c
end function           
           

--**
-- 
public function matrix_mult(sequence a,sequence b,atom row,atom column)
     c= repeat (repeat({0},row),column)
     for j = 1  to row   do
        for i = 1 to column do
            --if s = 2 then
                --b[j][i] = -b[j][i] 
            --end if
            c[j][i] = { a[j][i] * b[j][i]}
        end for
    end for
    return c
end function           

--**
-- 
public function fabs(object x)
  return abs(x)
end function


 --simple

--**
-- 
public function SQ(atom r )
   return  r * r
end function


--**
-- 
public function CUBE(atom r )

  return  r * r * r
end function


--**
-- 
public function d2r(atom x )
    --~ """is x *(pi/180) the same?

  return  (x * PI ) / 180.0 --need this for ann sin,cos,etc
end function


--**
-- 
public function r2d(atom x )

  return  ((x * 180.0) / PI )
end function

     -- //should be using rad2deg on the op side?


     -- //circumprence, cords of circle, area of sphere

--**
-- 
public function cordRH(atom r, atom h )

  return  2.0 * sqrt(h  * ((2.0 * r ) - h ))
end function


--**
-- 
public function cordRANG(atom r, atom ang )

  return  2.0 * r * sin(d2r(ang  / 2.0))
end function


--**
-- 
public function RCircum(atom c ) --?

  return  c / PI
end function


--**
-- 
public function CircumR(atom r )

  return  2 * PI * r 
end function


--**
-- 
public function CircumD(atom d )
 
  return  2 * PI * (d / 2.0)
end function


--**
-- 
public function dms2deg(sequence dms) 
    --~ """ from gcicle.py cousin stanley
    --~ no idea if this is accurate yet
    --~ >>> print dms2deg((75, 4, 43))
    --~ 75.0786111111

    --~ deg, mint, sec = dms
    --~ deg = dms[1]  mint = dms[2]  sec = dms[3] 
  return   dms[1]  + ( dms[2] / 60.0 ) + ( dms[3]  / 3600.0 )
end function
 
 --area volume


--**
-- return  m, r
public function rech2polar(atom x,atom y)
  return  {sqrt(SQ(x)+SQ(y)), arctan(d2r(y)/x)} 
end function

--**
-- return  x,y
public function polar2rech(atom m,atom r)
  return  {(r)*cos(d2r(m)), (r)*sin(d2r(m)) }
end function


--**
-- 
public function AreaCircle(atom r )

  return  PI * SQ(r )
end function

     -- //#define areasphere(r)  dia * circumphrence

--**
-- 
public function VolSphere(atom r )
 
  return  (4 * PI * CUBE(r )) / 3.0
end function


--**
-- 
public function AreaSphere(atom r )

  return  4 * PI * SQ(r )
end function


--**
-- 
public function VolCube(atom r )

  return  CUBE(r )
end function


--**
-- 
public function AreaCube(atom r )

  return  6 * SQ(r )
end function


--**
-- 
public function AreaRect(atom a, atom b )

  return a  *b 
end function


--**
-- 
public function VolBox(atom a, atom b, atom c)

  return a  * b  * c 
end function


--**
-- 
public function AreaBox(atom a, atom b, atom  c )
 
  return  2.0 * ((a  * b ) + (a  * c ) + (b  * c ))
end function


--**
-- 
public function VolCyl(atom h, atom r )

  return  PI * h  * SQ(r )
end function


--**
-- 
public function AreaCyl(atom r, atom h )

  return  2 * PI * r  * h 
end function


--**
-- 
public function inscribSQ(atom r )

  return  (r  + r ) * 0.7071
end function


--**
-- 
public function equalSQ(atom r )
 
  return  (r  + r ) * 0.8862
end function


--**
-- 
public function AreatriAB(atom a, atom b )

  return  (a  + b ) / 2.0
end function


--**
-- 
public function ABCo2(atom a, atom b, atom c )

  return  (a  + b  + c ) / 2.0
end function


--**
-- 
public function AreatriABE(atom a, atom b, atom ea )

  --~ return  a  * b  --still crash
  return  a  * b  * sin(d2r(ea ) / 2.0) --ok c*b/2? crash here?
  --~ return  a  * b  * sin(d2r(e ) / 2.0)--ok c*b/2?
  --~ return  a  * b  * r2d(sin(d2r(e ) / 2.0)) --
  --~ return  a  * b  * r2d(sin(d2r(e  / 2.0))) --
end function


--**
-- 
public function AreatriABC(atom a, atom b, atom c )

  return  sqrt(ABCo2(a, b, c ) * (ABCo2(a, b, c ) - a ) * (ABCo2(a, b, c ) - b ) * (ABCo2(a, b, c ) - c ))
end function
 
 --quant


--**
-- 
public function quat1x(atom x )

  return  abs(x )
end function


--**
-- 
public function quat2x(atom x )
 
  return  abs(x )
end function


--**
-- 
public function quat3x(atom x )

  return  - abs(x )
end function


--**
-- 
public function quat4x(atom x )

  return  - abs(x )
end function


--**
-- 
public function quat1y(atom y )

  return  abs(y )
end function


--**
-- 
public function quat2y(atom y )

  return  - abs(y )
end function


--**
-- 
public function quat3y(atom y )
 
  return  - abs(y )
end function


--**
-- 
public function quat4y(atom y )
 
  return  abs(y )
end function

 
--**
 --pythag F 90deg
-- 
public function sqrtPY(atom a, atom b )

    --~ from rpft.c *without  destructive underflow or overflow.
    --~ float aba,abb,xx,yy;

   atom aba, abb, xx, yy

    aba = fabs(a )     abb = fabs(b )
    xx = abb / aba    yy = aba / abb
    if aba > abb then
        return  (aba * sqrt(1.0 + SQ(xx )))
    elsif abb = 0.0 then
        return  0.0
    end if

  return  abb * sqrt(1.0 + SQ(yy ))
end function


--**
-- 
public function Aof90BC(atom b, atom c )

    --~ >>> print oAof90BC(2, 2 )
    --~ 2.82842712475

  return  sqrt(SQ(b ) + SQ(c )) --ok
end function


--**
-- 
public function oAof90BC(atom b, atom c )

    --~ >>> print Aof90BC(2, 2 )
    --~ 2.82842712475

  return  sqrtPY(b, c ) -- ?ok
end function


--**
-- 
public function Aof90BD(atom b, atom d )

    --~ >>> print Aof90BD(2, 2 )
    --~ 57.3074166957

  return  b  / sin(d2r(d ))
end function


--**
-- 
public function Aof90BE(atom b, atom ea )

    --~ >>> print Aof90BE(2, 2 )
    --~ 2.0012190886

  return  b  / cos(d2r(ea ))
end function


--**
-- 
public function Aof90CD(atom c, atom d )

    --~ >>> print Aof90CD(2, 2 )
    --~ 2.0012190886

  return  c  / cos(d2r(d ))
end function


--**
-- 
public function Aof90CE(atom c, atom ea )

    --~ >>> print Aof90CE(2, 2 )
    --~ 57.3074166957

  return  c  / sin(d2r(ea ))
end function
 

--**
-- pythag F !90
--  //doesnt work if F=90?
-- 
public function AofFBD(atom F, atom b, atom D )

    --~ >>> AofFBD(2, 2, 2 )
    --~ 2.0

  return  b  * sin(d2r(D )) / sin(d2r(F )) -- !k
end function


--**
-- 
public function Bof90AC(atom a, atom c )

    --~ >>> Bof90AC(2, 2.0 )
    --~ 0.0

  return  sqrt(SQ(a ) - SQ(c )) --b =
end function


--**
-- 
public function Bof90AE(atom a, atom ea )

    --~ >>> print Bof90AE(2, 2 )
    --~ 1.99878165404

  return  a  * cos(d2r(ea ))
end function


--**
-- 
public function Bof90AD(atom a, atom d )

    --~ >>> print Bof90AD(2, 2 )
    --~ 0.069798993405

  return  a  * sin(d2r(d ))
end function


--**
-- 
public function Bof90CD(atom c, atom d )

    --~ >>> print Bof90CD(2, 2 )
    --~ 0.0698415389835

  return  c  * tan(d2r(d ))
end function


--**
-- 
public function Bof90CE(atom c, atom ea )

    --~ >>> print Bof90CE(2, 2 )
    --~ 57.2725065658

     --return (c) * cot( d2r(e) )
  return  c  * (1.0 / tan(d2r(ea )))
end function


--**
-- 
public function BofFAD(atom F, atom a, atom d )

    --~ >>> BofFAD(2, 2, 2 )
    --~ 2.0

  return  (a  * sin(d2r(F ))) / sin(d2r(d )) -- !k
end function


--**
-- 
public function Cof90AB(atom a, atom b )

    --~ >>> Cof90AB(2, 2 )
    --~ 0.0

  return  sqrt(SQ(a ) - SQ(b )) --1 c=
end function


--**
-- 
public function Cof90AD(atom a, atom d )

    --~ >>> print Cof90AD(2, 2 )
    --~ 1.99878165404

  return  a  * cos(d2r(d ))
end function


--**
-- 
public function Cof90AE(atom a, atom ea )

    --~ >>> print Cof90AE(2, 2 )
    --~ 0.069798993405

  return  a  * sin(d2r(ea ))
end function


--**
-- 
public function Cof90BD(atom b, atom d )

    --~ >>> print Cof90BD(2, 2 )
    --~ 57.2725065658

     --return (b) * cot(d2r(d)) --b* (1/tan(d))
  return  b  * (1.0 / tan(d2r(d )))
end function


--**
-- 
public function Cof90BE(atom b, atom ea )

    --~ >>> print Cof90BE(2, 2 )
    --~ 0.0698415389835

  return  b  * tan(d2r(ea ))
end function


--**
-- 
public function CofABE(atom a, atom b, atom ea )

    --~ >>> print CofABE(2, 2, 2 )
    --~ 0.13959798681

  return  a  * b  * sin(d2r(ea )) -- !k
end function

     -- //tryed rearanging d2r , tryed atn,atanf asn,asinf

--**
-- 
public function Dof90AB(atom a, atom b )

    --~ >>> print Dof90AB(2, 2 )
    --~ 

  --~ return  arcsin(d2r((b ) / (a ))) -- !k d= #2 starrett cataloug ref
  --~ return  r2d( arcsin(d2r((b ) / (a ))))
  return  r2d( arcsin(b  / a ))
end function

     -- //   tanD= B/C  != atan(B/C)  != arctan(B/C)  ?

--**
-- 
public function Dof90BC(atom b, atom c )

    --~ >>> print Dof90BC(2, 2 )
    --~ 0.0174515206515

  return   r2d( arctan(b  / c ))
end function


--**
-- 
public function Dof90E(atom Ea )

    --~ >>> Dof90E(2 )
    --~ 88.0

  return  90.0 - Ea 
end function


--**
-- 
public function DofFE(atom F, atom ea )

    --~ >>> DofFE(2, 2 )
    --~ 176.0

  return  180.0 - F  + ea 
end function


--**
-- 
public function DofACE(atom a, atom c, atom ea )

    --~ >>> print DofACE(2, 2, 2 )
    --~ 0.000609203947136

  return  r2d(arcsin(c  * sin(d2r(ea ) / a )))
end function


--**
-- 
public function Eof90AC(atom a, atom c )

    --~ >>> print Eof90AC(2, 2 )
    --~ 0.0174541787376

  return  r2d(arcsin(c  /a ))
end function


--**
-- 
public function Eof90AB(atom a, atom b )

    --~ >>> Eof90AB(2, 2 )
    --~ 0.0


  return  Eof90AC(a , Cof90AB(a, b ))
end function


--**
-- 
public function Eof90D(atom D )

    --~ >>> Eof90D(2 )
    --~ 88.0

  return  90.0 -  D
end function


--**
-- 
public function EofFD(atom F, atom D )

    --~ >>> EofFD(2, 2 )
    --~ 176.0

  return  180.0 - D  + F 
end function


--**
-- 
public function EofACD(atom a, atom c, atom d )

    --~ >>> print EofACD(2, 2, 2 )
    --~ 0.000609203947136

  return  r2d(arcsin(c  * sin(d2r(d ) / a )))
end function


--**
-- 
public function FofABD(atom a, atom b, atom d )

    --~ >>> print FofABD(2, 2, 2 )
    --~ 0.000609203947136

  return  r2d(arcsin(b  * sin(d2r(d ) / a )))
end function


--**
-- 
public function FofED(atom Ea, atom d )

    --~ >>> FofED(2, 2 )
    --~ 176.0

  return  180.0 - d  + Ea 
end function

 

--**
--     triangle form from staret catalog around 1984
-- {{{
--           D
--          *  *
--       B *   *       A  
--      Opp *      *    Hyp
--         *         *
--         *            *
--         *              *  
--         F ************ E
--                C  Ajc
-- }}}
-- -determin which you have and provide the others
-- good structure would be a bitset
public function starret(atom a, atom b,atom c,atom d,atom ea,atom f)
     --check F for 90deg and compare results to know good results
     -- need rad/deg on some of these
 object msg
 
 msg = ""  
      
 if f = 90 then
     if not a  then
         if b and c then
          a = Aof90BC(b,c)
         elsif b and ea then
           a = Aof90BE(b, ea )
         elsif b and d then
           a = Aof90BD(b, d )
         elsif c and d then
           a = Aof90CD(c, d )
         elsif c and ea then
           a = Aof90CE(c, ea )
         else
            msg &= "A "  
         end if
     end if
   if not b  then
         if a and c then
          b = Bof90AC(a,c)
         elsif a and ea then
           b = Bof90AE(a, ea )
         elsif a and d then
           b = Bof90AD(a, d )
         elsif c and d then
           b = Bof90CD(c, d )
         elsif c and ea then
           b = Bof90CE(c, ea )
         else
            msg &= "B "  
         end if
   end if
   if not c  then
         if a and b then
          c = Cof90AB(a,b)
         elsif a and d then
           c = Cof90AD(a, d )
         elsif a and ea then
           c = Cof90AE(a, ea )
         elsif b and d then
           c = Cof90BD(b, d )
         elsif b and ea then
           c = Cof90BE(b, ea )
         else
            msg &= "C "  
         end if
   end if
   if not d  then
         if ea then
          d = Dof90E(ea)
          elsif a and b then
          d = Dof90AB(a,b)
         elsif b and c then
           d = Dof90BC(b, c )
         else
            msg &= "D "  
         end if
   end if
   if not ea  then
         if d  then
          ea = Eof90D(d)
         elsif a and c then
          ea = Eof90AC(a,c)
         elsif a and b then
           ea = Eof90AB(a, b )
         else
            msg &= "E "  
         end if
   end if
   --~ tri_calc()  --endless loop or crazy like a fox?     
 else
   if f then
     if not ea then
        if d then
           ea = EofFD(f, d)
        elsif a and c  and d then
           ea = EofACD(a, c, d)
        else
         msg &= "E "  
        end if
      end if
      
     if not d then
        if ea then
           d = DofFE(f, ea)
        elsif a and c  and ea then
           d = DofACE(a, c, ea)
        else
         msg &= "D "  
        end if
    end if
      
     if not a then
        if b  and d then
           a = AofFBD(f, b, d)
        else
         msg &= "A "  
        end if
    end if
      
     if not b then
        if b  and d then
           b = BofFAD(f, b, d)
        else
         msg &= "B "  
        end if
    end if
      
     if not c then
        if a  and b  and ea then
           c = CofABE(a, b, ea)
        else
         msg &= "C "  
        end if
    end if
 else      
        if a  and b  and d then
           f = FofABD(a, b, d)
        elsif ea  and d then
           f = FofED(ea, d)
        else
         msg &= "F "  
        end if
      
 end if
   
 end if
 return {msg, a, b, c, d, ea, f}
end function


--**
-- 
public function km2mi(atom mi)
  return   mi * 1.609344
end function
    

--**
-- 
public function mi2km(atom km)
  return   km / 1.609344
end function

--**
-- 
public function MHz2M(atom freq)
  return  300/freq
end function

--**
-- 
public function M2MHz(atom M)
  return   300*M
end function

--**
-- 
public function inch2M(atom inch)
  return   inch *.039376 * 10
end function

--**
-- 
public function M2inch(atom M)
  --~ return (M/10)*2.54
  return M * 39.37
end function

 --~ F/C/K DEGS
   --~ double cf=9.0/5.0; //F= 9/5(C) +32
   --~ double fc=5.0/9.0; //C= 5/9 (F-32)
--~ KELVIN+273.15
--~ CELSIUS
--~ FARENHEIT


--**
-- 
public function Dist(atom x, atom y, atom a, atom b )

  return  sqrt(SQ(x - a ) + SQ(y  - b ))
end function

--e
